﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using IronCow.UnitTests.Mock;
using NUnit.Framework.SyntaxHelpers;

namespace IronCow.UnitTests
{
    [TestFixture]
    public class TestTaskNotes
    {
        private MockRtm Rtm;

        [SetUp]
        public void SetUp()
        {
            Rtm = new MockRtm();
            Rtm.AddSuccessResponse("rtm.lists.getList",
                new MockListsResponsePart()
                {
                    new MockListResponsePart(987654321, "Inbox", TaskListFlags.Locked)
                });
        }

        [TearDown]
        public void TearDown()
        {
            Rtm = null;
        }

        [Test]
        public void TestAddNote()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            new MockTaskResponsePart(1)
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.notes.add",
                new MockTaskNoteResponsePart(1)
                {
                    Title = "Get them green",
                    Body = "Check with the clerk for fresh shipments."
                });
            Rtm.AddSuccessResponse("rtm.tasks.notes.edit",
                new MockTaskNoteResponsePart(1)
                {
                    Title = "Get them green while you can",
                    Body = "Check with the clerk for fresh shipments."
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Notes, Has.Count(0));
            var note = new TaskNote("Get them green", "Check with the clerk for fresh shipments.");
            task.Notes.Add(note);
            Assert.That(task.Notes, Has.Count(1));
            Assert.AreSame(note, task.Notes[0]);
            Assert.AreEqual("Get them green", note.Title);
            Assert.AreEqual("Check with the clerk for fresh shipments.", note.Body);

            note.Title = "Get them green while you can";
            Assert.AreEqual("Get them green while you can", note.Title);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestRemoveNote()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            Notes = { new MockTaskNoteResponsePart(123456789) { Title = "Note we don't need" } },
                            NestedParts = { new MockTaskResponsePart(1) }
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.notes.delete");

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Notes, Has.Count(1));
            Assert.AreEqual("Note we don't need", task.Notes[0].Title);
            task.Notes.Remove(task.Notes[0]);
            Assert.That(task.Notes, Has.Count(0));

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestCreateTaskWithNotes()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.add",
                new MockTaskListResponsePart(987654321)
                {
                    new MockTaskSeriesResponsePart(987654321, "Get Bananas")
                    {
                        new MockTaskResponsePart(123456789)
                    }
                });
            Rtm.AddSuccessResponse("rtm.tasks.notes.add",
                new MockTaskNoteResponsePart(1)
                {
                    Title = "Get them green",
                    Body = "Check with the clerk for fresh shipments."
                });
            Rtm.AddSuccessResponse("rtm.tasks.notes.edit",
                new MockTaskNoteResponsePart(1)
                {
                    Title = "Get them green while you can",
                    Body = "Check with the clerk for fresh shipments."
                });

            Task task = new Task();
            task.Name = "Get Bananas";
            TaskNote note = new TaskNote("Get them green", "Check with the clerk for fresh shipments.");
            task.Notes.Add(note);
            Assert.IsFalse(task.IsSynced);
            Assert.That(task.Notes, Has.Count(1));
            Assert.AreEqual("Get them green", task.Notes.First().Title);
            Assert.AreEqual("Check with the clerk for fresh shipments.", task.Notes.First().Body);

            TaskList list = Rtm.TaskLists[0];
            Assert.AreEqual(0, list.Tasks.Count);
            list.Tasks.Add(task);
            Assert.IsTrue(task.IsSynced);
            Assert.AreEqual(1, list.Tasks.Count);
            Assert.AreEqual("Get Bananas", task.Name);
            Assert.That(task.Notes, Has.Count(1));
            Assert.AreSame(note, task.Notes[0]);
            Assert.That(note.IsSynced);
            Assert.AreEqual("Get them green", note.Title);
            Assert.AreEqual("Check with the clerk for fresh shipments.", note.Body);

            note.Title = "Get them green while you can";
            Assert.AreEqual("Get them green while you can", note.Title);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestEditTaskNote()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            Notes = { new MockTaskNoteResponsePart(123456789) { Title = "A test note" } },
                            NestedParts = { new MockTaskResponsePart(1) }
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.notes.edit",
                new MockTaskNoteResponsePart(123456789)
                {
                    Title = "A test note",
                    Body = "Nothing to say here"
                });
            Rtm.AddSuccessResponse("rtm.tasks.notes.edit",
                new MockTaskNoteResponsePart(123456789)
                {
                    Title = "A test note that isn't useful",
                    Body = "Nothing to say here"
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Notes, Has.Count(1));

            TaskNote note = task.Notes[0];
            Assert.AreEqual("A test note", note.Title);
            Assert.That(note.Body, Is.Empty);
            note.Body = "Nothing to say here";
            Assert.AreEqual("A test note", note.Title);
            Assert.AreEqual("Nothing to say here", note.Body);
            note.Title = "A test note that isn't useful";
            Assert.AreEqual("A test note that isn't useful", note.Title);
            Assert.AreEqual("Nothing to say here", note.Body);

            Rtm.EnsureAllResponsesUsed();
        }

        [Test]
        public void TestEditTaskNoteBeforeSynced()
        {
            Rtm.AddSuccessResponse("rtm.tasks.getList",
                new MockTasksResponsePart()
                {
                    new MockTaskListResponsePart(987654321)
                    {
                        new MockTaskSeriesResponsePart(1, "Get Bananas")
                        {
                            new MockTaskResponsePart(1)
                        }
                    }
                });
            Rtm.AddTimelineResponse();
            Rtm.AddSuccessResponse("rtm.tasks.notes.add",
                new MockTaskNoteResponsePart(1)
                {
                    Title = "Get them green",
                    Body = "Check with the clerk for fresh shipments."
                });

            TaskList inbox = Rtm.TaskLists[0];
            Assert.That(inbox.Tasks, Has.Count(1));
            Task task = inbox.Tasks[0];
            Assert.That(task.Notes, Has.Count(0));

            var note = new TaskNote("Green!");
            note.Title = "Get them green";
            note.Body = "Check with the clerk for fresh shipments.";

            task.Notes.Add(note);
            Assert.That(task.Notes, Has.Count(1));
            Assert.AreSame(note, task.Notes[0]);
            Assert.AreEqual("Get them green", note.Title);
            Assert.AreEqual("Check with the clerk for fresh shipments.", note.Body);

            Rtm.EnsureAllResponsesUsed();
        }
    }
}
